package com.Rpc远程调用简单版.client;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.Socket;

public class RpcInvocationClientHandler  {

    private Socket socket ;

    public RpcInvocationClientHandler(String address , Integer port) {
        try {
            this.socket = new Socket(address,port);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 远程代理方法
     * @param clazz  需要代理的接口类
     * @return
     */
    public  Object proxy(Class<?> clazz) {

        /**
         * 动态代理
         */
        return Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{clazz}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {


                /***
                 * Object输入输出流
                 */
                ObjectInputStream objectInputStream = null;

                ObjectOutputStream objectOutputStream  = null ;




                try {



                    objectOutputStream = new ObjectOutputStream(socket.getOutputStream());


                    /**
                     * 发送接口的普通名称
                     */
                    objectOutputStream.writeUTF(clazz.getSimpleName());


                    objectOutputStream.writeUTF(method.getName());


                    /**
                     * 发送 参数类型
                     */

                    objectOutputStream.writeObject(method.getParameterTypes());


                    /**
                     * 发送 参数项
                     */
                    objectOutputStream.writeObject(args);




                    objectOutputStream.flush();


                    /**
                     * 读输入流
                     */
                    objectInputStream = new ObjectInputStream( socket.getInputStream());

                    Object object = objectInputStream.readObject();


                    return  object;

                } catch (IOException e) {
                    e.printStackTrace();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
                finally {

                    objectInputStream.close();
                    objectOutputStream.close();
                    socket.close();
                }

                return null;
            }


        });

    }
}
